import { Buffer } from 'node:buffer'
import { generateStartCommand, generateStopCommand, getTIDList } from 'rfid-utils'
import { SerialPort } from 'serialport'
import { updateCountdown, updateScreen } from './screen'
import { getRfidConfig } from './utils/config'
import logger from './utils/logger'
import { MessageQueue } from './utils/util'

// RFID模块状态
interface RfidModuleState {
  initialized: boolean
  connected: boolean
  isReading: boolean
  lastError: Error | null
  lastSuccessfulRead: Date | null
}

const rfidState: RfidModuleState = {
  initialized: false,
  connected: false,
  isReading: false,
  lastError: null,
  lastSuccessfulRead: null,
}

let rfidConfig: any
let port: SerialPort | null = null
let countdown: number = 0
let timer: NodeJS.Timeout | null = null
let messageQueue: MessageQueue

/**
 * 安全加载RFID配置
 */
function loadRfidConfiguration(): boolean {
  try {
    rfidConfig = getRfidConfig()

    // 验证配置完整性
    if (!rfidConfig) {
      throw new Error('RFID配置加载失败')
    }

    if (!rfidConfig.serialPort || !rfidConfig.serialPort.path) {
      throw new Error('RFID串口路径配置无效')
    }

    if (!rfidConfig.serialPort.baudRate || rfidConfig.serialPort.baudRate <= 0) {
      throw new Error('RFID串口波特率配置无效')
    }

    if (!rfidConfig.antennaIds || !Array.isArray(rfidConfig.antennaIds) || rfidConfig.antennaIds.length === 0) {
      throw new Error('RFID天线ID配置无效')
    }

    if (!rfidConfig.readingTimeout || rfidConfig.readingTimeout <= 0) {
      throw new Error('RFID读取超时配置无效')
    }

    countdown = rfidConfig.readingTimeout
    messageQueue = new MessageQueue()

    return true
  }
  catch (error) {
    const err = error as Error
    rfidState.lastError = err
    logger.error('RFID模块: 配置加载失败', {
      error: err.message,
      solution: '请检查config.json文件中的hardware.rfid配置项是否正确',
    })
    return false
  }
}

/**
 * 处理串口连接成功
 */
function handlePortOpen(): void {
  logger.info('RFID模块: 串口连接成功')
  rfidState.connected = true
  rfidState.lastError = null
}

/**
 * 处理串口数据接收
 */
function handlePortData(data: Buffer): void {
  try {
    const hexData = data.toString('hex')
    logger.debug('RFID模块: 接收到数据', { data: hexData })

    messageQueue.add(hexData)
    rfidState.lastSuccessfulRead = new Date()
  }
  catch (error) {
    const err = error as Error
    logger.error('RFID模块: 数据处理失败', {
      error: err.message,
      rawData: data.toString('hex'),
    })
  }
}

/**
 * 处理串口错误
 */
function handlePortError(error: Error): void {
  rfidState.connected = false
  rfidState.lastError = error

  let solution = '请检查RFID设备连接和串口配置'
  if (error.message.includes('permission') || error.message.includes('access')) {
    solution = '请检查串口权限，确保当前用户有访问串口设备的权限'
  }
  else if (error.message.includes('no such file') || error.message.includes('ENOENT')) {
    solution = '串口设备不存在，请检查设备是否正确连接'
  }
  else if (error.message.includes('busy') || error.message.includes('resource')) {
    solution = '串口设备被占用，请检查是否有其他程序正在使用该串口'
  }

  logger.error(`RFID模块串口错误: ${error.message}`, {
    error: error.message,
    solution,
  })
}

/**
 * 处理串口关闭
 */
function handlePortClose(): void {
  rfidState.connected = false
  logger.warn('RFID模块串口连接已关闭')
}

/**
 * 创建串口连接
 */
function createSerialPortConnection(): void {
  try {
    if (port && !port.destroyed) {
      port.close()
    }

    logger.info('RFID模块: 正在创建串口连接...', {
      path: rfidConfig.serialPort.path,
      baudRate: rfidConfig.serialPort.baudRate,
    })

    port = new SerialPort({
      path: rfidConfig.serialPort.path,
      baudRate: rfidConfig.serialPort.baudRate,
    })

    // 绑定事件处理器
    port.on('open', handlePortOpen)
    port.on('data', handlePortData)
    port.on('error', handlePortError)
    port.on('close', handlePortClose)
  }
  catch (error) {
    const err = error as Error
    logger.error('RFID模块: 创建串口连接失败', {
      error: err.message,
      path: rfidConfig.serialPort.path,
      solution: '请检查串口设备是否存在且可访问',
    })

    handlePortError(err)
  }
}

/**
 * 初始化RFID模块
 */
export function initRfid(): void {
  logger.info('RFID模块: 正在初始化...')
  try {
    // 重置状态
    rfidState.initialized = false
    rfidState.connected = false
    rfidState.lastError = null

    // 加载配置
    if (!loadRfidConfiguration()) {
      throw new Error('配置加载失败')
    }

    // 创建串口连接
    createSerialPortConnection()

    rfidState.initialized = true
  }
  catch (error) {
    const err = error as Error
    rfidState.lastError = err

    logger.error(`RFID模块初始化失败: ${err.message}`, {
      error: err.message,
      solution: '请检查RFID设备连接和配置文件',
    })

    throw err
  }
}

/**
 * 安全写入命令到串口
 */
function writeCommand(command: Buffer | string): Promise<boolean> {
  return new Promise((resolve) => {
    if (!port || !rfidState.connected) {
      logger.error('RFID模块串口未连接，无法写入命令', {
        error: '串口未连接',
        solution: '请等待串口连接成功后再试',
      })
      resolve(false)
      return
    }

    try {
      const commandBuffer = Buffer.isBuffer(command) ? command : Buffer.from(command, 'hex')
      // logger.debug(`RFID模块: 写入命令:${commandBuffer.toString('hex')}`)
      logger.info(`RFID模块: 写入命令:${commandBuffer.toString('hex')}`)

      port.write(commandBuffer, (err) => {
        if (err) {
          logger.error(`RFID模块命令写入失败: ${err.message}`, {
            error: err.message,
            solution: '请检查串口连接状态',
          })
          resolve(false)
        }
        else {
          resolve(true)
        }
      })
    }
    catch (error) {
      const err = error as Error
      logger.error('RFID模块: 命令处理失败', {
        error: err.message,
        command: command.toString(),
      })
      resolve(false)
    }
  })
}

/**
 * 开始RFID读取
 */
export async function startReading(): Promise<void> {
  try {
    logger.info('RFID模块: 开始读取请求...')

    // 检查模块状态
    if (!rfidState.initialized) {
      throw new Error('RFID模块未初始化')
    }

    if (!rfidState.connected) {
      throw new Error('RFID串口未连接')
    }

    // 重置消息队列
    messageQueue.reset()

    if (!rfidState.isReading) {
      logger.info('RFID模块: 启动读取器...')

      try {
        const antennaIds = rfidConfig.antennaIds
        const startCommand = generateStartCommand(antennaIds)

        // 先停止，再启动
        const stopSuccess = await writeCommand(generateStopCommand())
        if (!stopSuccess) {
          logger.warn('RFID模块: 停止命令发送失败，继续尝试启动')
        }

        const startSuccess = await writeCommand(startCommand)
        if (!startSuccess) {
          throw new Error('启动命令发送失败')
        }

        logger.info(`RFID模块: 读取器启动成功, 天线ID:${antennaIds.join(',')}`)
      }
      catch (error) {
        const err = error as Error
        logger.error('RFID模块: 读取器启动失败', {
          error: err.message,
          solution: '请检查RFID设备连接和天线配置',
        })
        throw err
      }
    }

    rfidState.isReading = true
    countdown = rfidConfig.readingTimeout

    // 清除之前的定时器
    if (timer) {
      clearInterval(timer)
    }

    // 更新屏幕倒计时
    try {
      updateCountdown(countdown)
    }
    catch (error) {
      // 屏幕更新失败不影响核心功能，降级为调试日志
      logger.debug(`RFID模块屏幕倒计时更新失败: ${(error as Error).message}`)
    }

    // 启动倒计时
    timer = setInterval(() => {
      countdown--

      try {
        updateCountdown(countdown)
      }
      catch (error) {
        // 屏幕更新失败不影响核心功能，降级为调试日志
        logger.debug(`RFID模块倒计时显示更新失败: ${(error as Error).message}`)
      }

      if (countdown <= 0) {
        stopReading()
        if (timer) {
          clearInterval(timer)
          timer = null
        }
      }
    }, rfidConfig.countdownInterval)
  }
  catch (error) {
    const err = error as Error
    rfidState.lastError = err

    logger.error('RFID模块: 启动读取失败', {
      error: err.message,
      connected: rfidState.connected,
      initialized: rfidState.initialized,
      solution: '请检查RFID模块状态和设备连接',
    })

    throw err
  }
}

/**
 * 停止RFID读取
 */
async function stopReading(): Promise<void> {
  try {
    logger.info('RFID模块: 停止读取...')

    const stopSuccess = await writeCommand(generateStopCommand())
    if (!stopSuccess) {
      logger.warn('RFID模块: 停止命令发送失败')
    }

    await getRfidTIDList()
    rfidState.isReading = false

    logger.info('RFID模块: 读取已停止')
  }
  catch (error) {
    const err = error as Error
    logger.error('RFID模块: 停止读取时发生错误', {
      error: err.message,
    })
    rfidState.isReading = false
  }
}

/**
 * 获取并处理RFID TID列表
 */
async function getRfidTIDList(): Promise<void> {
  try {
    const data = messageQueue.getData()
    const TIDList = getTIDList(data)

    logger.info(`RFID模块: 检测到 RFID 数量 ${TIDList.length}`)

    // 更新屏幕显示
    try {
      updateScreen(TIDList.length)
    }
    catch (error) {
      // 屏幕更新失败不影响核心功能，降级为调试日志
      logger.debug(`RFID模块屏幕更新失败: ${(error as Error).message}`)
    }
  }
  catch (error) {
    const err = error as Error
    logger.error(`RFID模块TID列表处理失败: ${err.message}`, {
      error: err.message,
      solution: '请检查RFID数据格式和处理逻辑',
    })
  }
}

/**
 * 清理RFID模块资源
 */
export async function cleanup(): Promise<void> {
  try {
    logger.info('RFID模块: 开始清理资源...')

    // 停止读取
    rfidState.isReading = false

    // 清除定时器
    if (timer) {
      clearInterval(timer)
      timer = null
    }

    // 发送停止命令
    const stopCommand = Buffer.from('5A000102FF0000885A', 'hex')
    const stopSuccess = await writeCommand(stopCommand)
    if (!stopSuccess) {
      logger.warn('RFID模块: 清理时停止命令发送失败')
    }

    // 关闭串口
    if (port && !port.destroyed) {
      port.close((err) => {
        if (err) {
          logger.error('RFID模块: 串口关闭失败', {
            error: err.message,
          })
        }
        else {
          logger.info('RFID模块: 串口已关闭')
        }
      })
    }

    rfidState.connected = false
    rfidState.initialized = false

    logger.info('RFID模块: 资源清理完成')
  }
  catch (error) {
    const err = error as Error
    logger.error('RFID模块: 资源清理失败', {
      error: err.message,
    })
  }
}

/**
 * 获取RFID模块状态
 */
export function getRfidStatus(): RfidModuleState {
  return { ...rfidState }
}
